Restore proactive OAuth token refresh for Desktop mode#402
Merged
saucow merged 1 commit intodocker:release/0.39.1from Feb 13, 2026
Merged
Restore proactive OAuth token refresh for Desktop mode#402saucow merged 1 commit intodocker:release/0.39.1from
saucow merged 1 commit intodocker:release/0.39.1from
Conversation
Secrets Engine response metadata (added in Pinata PR #38931)
- Restore eventChan, SendEvent, and CE/Desktop refresh split in Provider
- Restore routeEventToProvider for SSE event routing in run.go
- Start Provider loops in both CE and Desktop modes
- Handle EventTokenRefresh via InvalidateOAuthClients directly (not
routed to Provider) to avoid a reloadFn → Filter → SSE → reloadFn
infinite loop caused by Pinata's Filter triggering RefreshToken within
the 5-minute window before the oauth2 library's 10-second threshold
- Add zero-ExpiresAt guard to prevent busy loop when metadata is missing
slimslenderslacks
approved these changes
Feb 13, 2026
| // Desktop mode: Trigger refresh via Desktop API | ||
| go func() { | ||
| authClient := desktop.NewAuthClient() | ||
| app, err := authClient.GetOAuthApp(context.Background(), p.name) |
Collaborator
There was a problem hiding this comment.
won't be cancelled if the provider stops
| return &Provider{ | ||
| name: name, | ||
| stopChan: make(chan struct{}), | ||
| eventChan: make(chan Event), |
Collaborator
There was a problem hiding this comment.
trying to think if this chan needs any buffering just in case we get a send before a receive but I don't think that's possible here.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What I did
Restored the proactive OAuth token refresh Provider loop for Desktop mode. This was removed in #247 (Secrets Engine migration) under the assumption that SSE notifications would handle refresh reactively. In practice, tokens sat in HTTP headers for their full lifetime with no proactive refresh — tool calls would fail once the token expired.
Key changes
Provider loop runs in both CE and Desktop modes. Previously only CE mode had a polling loop that tracked token expiry and triggered refresh before tokens expired. Desktop mode relied entirely on reactive SSE events.
Desktop mode reads token expiry from Secrets Engine metadata. The
GetTokenStatus()function now readsExpiryAtfrom the Secrets Engine response metadata in Desktop mode, with graceful fallback when metadata is unavailable (older versions).Restored SSE event routing.
EventLoginSuccessis routed to the Provider to trigger reload and reset retry counters.EventLogoutSuccessstops the Provider.EventTokenRefresh handled via connection invalidation only. Token refresh SSE events invalidate cached connections directly (
InvalidateOAuthClients) instead of being routed to the Provider. This prevents an infinite loop wherereloadFntriggers a Secrets Engine query → the Secrets Engine'sFilter()callsRefreshToken()→ the oauth2 library returns the same token (still valid) → another SSE event is sent → loop repeats. The Provider's timer handles refresh scheduling independently.Retry safeguards. Exponential backoff (30s → 1m → 2m → ... up to 7 attempts) when a refresh doesn't update the token expiry. Zero-expiry guard prevents busy loop when metadata is missing.
Related issue
Addresses the gap where OAuth tokens expired without proactive refresh in Desktop mode, requiring users to re-authenticate manually after token expiry.
Related: #247